﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using starLiGHT.Collections;
using Microsoft.Xna.Framework;

namespace starLiGHT.Engine.Tests
{
    public class QTestNode : IQuadNode
    {
        RectangleF bounds;

        public event EventHandler BoundsChanged;

        public QTestNode(RectangleF bounds)
        {
            this.Bounds = bounds;
        }

        public RectangleF Bounds
        {
            get { return bounds; }
            set
            {
                if (bounds != value)
                {
                    bounds = value;
                    if (BoundsChanged != null) BoundsChanged(this, null);
                }
            }
        }
    }

    [TestFixture]
    public class QuadTree
    {
        QuadTree<QTestNode> quadTree;

        [SetUp]
        public void Setup()
        {
            quadTree = new QuadTree<QTestNode>(new Vector2(1.0f, 1.0f), 1);
        }

        [Test]
        public void Constructor01()
        {
            quadTree = new QuadTree<QTestNode>(new Vector2(5.0f, 7.0f), 5);

            Assert.AreEqual(new Vector2(5.0f, 7.0f), quadTree.MinLeafSize);
            Assert.AreEqual(5, quadTree.MaxObjectsPerLeaf);
            Assert.AreEqual(false, quadTree.Sort);
        }

        [Test]
        public void Constructor02()
        {
            quadTree = new QuadTree<QTestNode>(new Vector2(15.0f, 17.0f), 105, true);

            Assert.AreEqual(new Vector2(15.0f, 17.0f), quadTree.MinLeafSize);
            Assert.AreEqual(105, quadTree.MaxObjectsPerLeaf);
            Assert.AreEqual(true, quadTree.Sort);
        }

        [Test]
        public void Synchronized01()
        {
            Assert.AreEqual(true, quadTree.IsSynchronized);
        }

        [Test]
        public void Count01()
        {
            Assert.AreEqual(0, quadTree.Count);

            for (int i = 0; i < 5; i++)
            {
                quadTree.Insert(new QTestNode(new RectangleF(0.5f, 0.5f, 0.5f, 0.5f)));
                Assert.AreEqual(i + 1, quadTree.Count);
            }
        }

        [Test]
        public void Count02()
        {
            List<QTestNode> nodesToRemove = new List<QTestNode>();

            Assert.AreEqual(0, quadTree.Count);

            for (int i = 0; i < 5; i++)
            {
                QTestNode qtn = new QTestNode(new RectangleF(0.5f * i, 0.5f * i, 0.5f, 0.5f));
                quadTree.Insert(qtn);
                nodesToRemove.Add(qtn);
                Assert.AreEqual(i + 1, quadTree.Count);
            }

            for (int i = 0; i < 5; i++)
            {
                QTestNode qtn = nodesToRemove[0];
                quadTree.Remove(qtn);
                nodesToRemove.Remove(qtn);
                Assert.AreEqual(5 - 1 - i, quadTree.Count);
            }
        }

    }
}
